package com.tencent.wxcloudrun.service.business.fangdong;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tencent.wxcloudrun.config.UserContext;
import com.tencent.wxcloudrun.pojo.bo.HouseStatusEnum;
import com.tencent.wxcloudrun.pojo.bo.NoticeConstant;
import com.tencent.wxcloudrun.pojo.dto.resp.GetCurLiveDetailResp;
import com.tencent.wxcloudrun.pojo.dto.resp.GetTenantListResp;
import com.tencent.wxcloudrun.pojo.po.*;
import com.tencent.wxcloudrun.service.*;
import com.tencent.wxcloudrun.service.business.NoticeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TenantManageService {

    @Resource
    private XHelpmateInfoService xHelpmateInfoService;

    @Resource
    private XHouseInfoService xHouseInfoService;

    @Resource
    private XFeeManageMasterService xFeeManageMasterService;

    @Resource
    private XPersonInfoService xPersonInfoService;

    @Resource
    private XContractManageService xContractManageService;

    @Resource
    private NoticeService noticeService;

    public List<GetTenantListResp> getTenantList() {
        List<GetTenantListResp> respList = new ArrayList<>();
        String openId = UserContext.getOpenId();
        // 先检查是房东还是助理，然后获取其对应的房屋列表信息
        LambdaQueryWrapper<XHelpmateInfo> xHelpmateInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHelpmateInfoLambdaQueryWrapper.eq(XHelpmateInfo::getHelpmateId, openId);
        XHelpmateInfo xHelpmateInfo = xHelpmateInfoService.getOne(xHelpmateInfoLambdaQueryWrapper);
        if (xHelpmateInfo == null || StrUtil.isBlank(xHelpmateInfo.getHelpmateId())) { // 表明当前人肯定是房东
            LambdaQueryWrapper<XHouseInfo> xHouseInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            xHouseInfoLambdaQueryWrapper.eq(XHouseInfo::getLandlordId, openId);
            List<XHouseInfo> houseInfoList = xHouseInfoService.list(xHouseInfoLambdaQueryWrapper);
            if (CollUtil.isEmpty(houseInfoList)) {
                return respList;
            }
            List<String> houseIdList = houseInfoList.stream().map(XHouseInfo::getHouseId).collect(Collectors.toList());
            return getGetTenantListResps(respList, houseIdList);
        }
        // 如果是助理
        List<String> houseList = JSON.parseArray(xHelpmateInfo.getHouseList(), String.class);
        return getGetTenantListResps(respList, houseList);
    }

    private List<GetTenantListResp> getGetTenantListResps(List<GetTenantListResp> respList, List<String> houseIdList) {
        LambdaQueryWrapper<XFeeManageMaster> xFeeManageMasterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageMasterLambdaQueryWrapper.eq(XFeeManageMaster::getEffect, "yes");
        xFeeManageMasterLambdaQueryWrapper.in(XFeeManageMaster::getHouseId, houseIdList);
        List<XFeeManageMaster> xFeeManageMasters = xFeeManageMasterService.list(xFeeManageMasterLambdaQueryWrapper);
        if (CollUtil.isEmpty(xFeeManageMasters)) {
            return respList;
        }
        for (XFeeManageMaster manageMaster : xFeeManageMasters) {
            GetTenantListResp tenantListResp = new GetTenantListResp();
            tenantListResp.setLiveId(manageMaster.getBusinessId());
            LambdaQueryWrapper<XPersonInfo> xPersonInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonId, manageMaster.getTenantId());
            xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonType, "tenant");
            XPersonInfo personInfo = xPersonInfoService.getOne(xPersonInfoLambdaQueryWrapper);
            tenantListResp.setNameSexNum(personInfo.getCardName() + "_" + personInfo.getSex() + "_" + manageMaster.getPersonNum() + "人");
            tenantListResp.setRentTime(DateUtil.format(manageMaster.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
            DateTime endDate = null;
            if (manageMaster.getLiveYmd().equals("日")) {
                endDate = DateUtil.offsetDay(manageMaster.getCreateTime(), manageMaster.getLiveNum());
            }
            if (manageMaster.getLiveYmd().equals("月")) {
                endDate = DateUtil.offsetMonth(manageMaster.getCreateTime(), manageMaster.getLiveNum());
            }
            if (manageMaster.getLiveYmd().equals("年")) {
                endDate = DateUtil.offsetMonth(manageMaster.getCreateTime(), manageMaster.getLiveNum() * 12);
            }
            long between = DateUtil.between(manageMaster.getCreateTime(), endDate, DateUnit.DAY);
            tenantListResp.setLeftDays("剩" + between + "天");
            respList.add(tenantListResp);
        }
        return respList;
    }

    public GetCurLiveDetailResp getCurLiveDetail(String liveId) {
        LambdaQueryWrapper<XFeeManageMaster> xFeeManageMasterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageMasterLambdaQueryWrapper.eq(XFeeManageMaster::getBusinessId, liveId);
        XFeeManageMaster one = xFeeManageMasterService.getOne(xFeeManageMasterLambdaQueryWrapper);
        GetCurLiveDetailResp getCurLiveDetailResp = new GetCurLiveDetailResp();
        LambdaQueryWrapper<XPersonInfo> xPersonInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonId, one.getTenantId());
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonType, "tenant");
        XPersonInfo personInfo = xPersonInfoService.getOne(xPersonInfoLambdaQueryWrapper);
        getCurLiveDetailResp.setName(personInfo.getCardName());
        getCurLiveDetailResp.setSex(personInfo.getSex());
        getCurLiveDetailResp.setNum(String.valueOf(one.getPersonNum()));
        LambdaQueryWrapper<XHouseInfo> xHouseInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseInfoLambdaQueryWrapper.eq(XHouseInfo::getHouseId, one.getHouseId());
        XHouseInfo houseInfo = xHouseInfoService.getOne(xHouseInfoLambdaQueryWrapper);
        getCurLiveDetailResp.setHouseId(houseInfo.getHouseId());
        getCurLiveDetailResp.setHouseName(houseInfo.getHouseName());
        getCurLiveDetailResp.setRentTime(DateUtil.format(one.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
        DateTime endDate = null;
        if (one.getLiveYmd().equals("日")) {
            endDate = DateUtil.offsetDay(one.getCreateTime(), one.getLiveNum());
        }
        if (one.getLiveYmd().equals("月")) {
            endDate = DateUtil.offsetMonth(one.getCreateTime(), one.getLiveNum());
        }
        if (one.getLiveYmd().equals("年")) {
            endDate = DateUtil.offsetMonth(one.getCreateTime(), one.getLiveNum() * 12);
        }
        long between = DateUtil.between(one.getCreateTime(), endDate, DateUnit.DAY);
        getCurLiveDetailResp.setLeftDays(String.valueOf(between));
        getCurLiveDetailResp.setMonthRent(one.getMouthFee().toPlainString());
        getCurLiveDetailResp.setManageFee(one.getManageFee().toPlainString());
        getCurLiveDetailResp.setDeposit(one.getDeposit().toPlainString());
        getCurLiveDetailResp.setTotalFee(NumberUtil.add(one.getMouthFee(), one.getManageFee(), one.getDeposit()).toPlainString());
        return getCurLiveDetailResp;
    }

    public String getTenantPhone(String liveId) {
        LambdaQueryWrapper<XFeeManageMaster> xFeeManageMasterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageMasterLambdaQueryWrapper.eq(XFeeManageMaster::getBusinessId, liveId);
        XFeeManageMaster one = xFeeManageMasterService.getOne(xFeeManageMasterLambdaQueryWrapper);
        LambdaQueryWrapper<XPersonInfo> xPersonInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonId, one.getTenantId());
        xPersonInfoLambdaQueryWrapper.eq(XPersonInfo::getPersonType, "tenant");
        XPersonInfo personInfo = xPersonInfoService.getOne(xPersonInfoLambdaQueryWrapper);
        return personInfo.getPhone();
    }

    @Transactional
    public String forceExpel(String liveId) {
        String openId = UserContext.getOpenId();
        Date date = new Date();
        LambdaQueryWrapper<XFeeManageMaster> xFeeManageMasterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageMasterLambdaQueryWrapper.eq(XFeeManageMaster::getBusinessId, liveId);
        XFeeManageMaster one = xFeeManageMasterService.getOne(xFeeManageMasterLambdaQueryWrapper);

        // 获取房屋信息
        LambdaQueryWrapper<XHouseInfo> xHouseInfoQueryWrapper = new LambdaQueryWrapper<>();
        xHouseInfoQueryWrapper.eq(XHouseInfo::getHouseId, one.getHouseId());
        XHouseInfo houseInfo = xHouseInfoService.getOne(xHouseInfoQueryWrapper);

        // 删除合同
        LambdaQueryWrapper<XContractManage> xContractManageLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xContractManageLambdaQueryWrapper.eq(XContractManage::getContractId, one.getContractId());
        xContractManageService.remove(xContractManageLambdaQueryWrapper);
        // 费用管理主表设置为不生效
        XFeeManageMaster xFeeManageMaster = new XFeeManageMaster();
        xFeeManageMaster.setEffect("no");
        xFeeManageMaster.setUpdateTime(date);
        xFeeManageMasterService.update(xFeeManageMaster, xFeeManageMasterLambdaQueryWrapper);
        // 更改x_house_info表的房屋状态为可出租
        XHouseInfo xHouseInfo = new XHouseInfo();
        xHouseInfo.setHouseState(HouseStatusEnum.WAIT_RENT.getValue());
        xHouseInfo.setUpdateId(openId);
        xHouseInfo.setUpdateTime(date);
        LambdaQueryWrapper<XHouseInfo> xHouseInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseInfoLambdaQueryWrapper.eq(XHouseInfo::getHouseId, one.getHouseId());
        xHouseInfoService.update(xHouseInfo, xHouseInfoLambdaQueryWrapper);

        // 增加通知信息
        // 检查这个房子是否有助理在管理
        LambdaQueryWrapper<XHelpmateInfo> xHelpmateInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHelpmateInfoLambdaQueryWrapper.eq(XHelpmateInfo::getLandlordId, houseInfo.getLandlordId());
        xHelpmateInfoLambdaQueryWrapper.like(XHelpmateInfo::getHouseList, one.getHouseId());
        List<XHelpmateInfo> helpList = xHelpmateInfoService.list(xHelpmateInfoLambdaQueryWrapper);

        // 找出租客的个人信息
        LambdaQueryWrapper<XPersonInfo> xPersonInfoTenant = new LambdaQueryWrapper<>();
        xPersonInfoTenant.eq(XPersonInfo::getPersonId, one.getTenantId());
        xPersonInfoTenant.eq(XPersonInfo::getPersonType, "tenant");
        XPersonInfo tenantInfo = xPersonInfoService.getOne(xPersonInfoTenant);

        // 找出房东的个人信息
        LambdaQueryWrapper<XPersonInfo> xPersonInfoLand = new LambdaQueryWrapper<>();
        xPersonInfoLand.eq(XPersonInfo::getPersonId, houseInfo.getLandlordId());
        xPersonInfoLand.eq(XPersonInfo::getPersonType, "landlord");
        XPersonInfo landInfo = xPersonInfoService.getOne(xPersonInfoLand);

        int helpFlag = 0; // 0表示没有助理，1表示有助理
        if (CollUtil.isNotEmpty(helpList)) { // 表明这间房子有助理在管理，甚至可能有多个，给他们发送通知
            for (XHelpmateInfo xHelpmateInfo : helpList) {
                ++helpFlag;
                noticeService.createNoticeByOpenid(xHelpmateInfo.getHelpmateId(), "helpmate",
                        NoticeConstant.FORCE_EXPEL_HELP_TITLE,
                        String.format(NoticeConstant.FORCE_EXPEL_HELP_CONTENT,
                                tenantInfo.getCardName(), tenantInfo.getPhone()));
            }
        }
        // 给房东发送通知
        noticeService.createNoticeByOpenid(houseInfo.getLandlordId(), "land",
                NoticeConstant.FORCE_EXPEL_LAND_TITLE,
                String.format(NoticeConstant.FORCE_EXPEL_LAND_CONTENT,
                        tenantInfo.getCardName(),
                        tenantInfo.getPhone(),
                        (helpFlag == 0 ? "" : "，该信息已同步至助理")));
        // 给被强制退租的租客发送通知
        noticeService.createNoticeByOpenid(one.getTenantId(), "tenant",
                NoticeConstant.FORCE_EXPEL_TENANT_TITLE,
                String.format(NoticeConstant.FORCE_EXPEL_TENANT_CONTENT,
                        (helpFlag == 0 ? landInfo.getCardName() : helpList.get(0).getAlias()),
                        (helpFlag == 0 ? landInfo.getPhone() : helpList.get(0).getHelpPhone())));
        return "强制退租成功";
    }
}
